`include "sdr_head.v"

module sdr_read(
    input                   clk,
    input                   cap_clk,
    input                   read_en,
    input       [15 : 0]    sdr_dq,
    input       [24 : 0]    int_addr,
    output reg              read_done,
    output reg  [31 : 0]    rdata,
    output      [19 : 0]    rd_bus
);

    localparam  start = 8'd0;
    localparam  read = start + `TRCD;
    localparam  loadl = read + `SL + `CL + 1'b1;
    localparam  loadh = loadl + 1'b1;
    localparam  finish = loadh + 1'b1;

    reg [7  : 0]    count;
    reg [12 : 0]    sdr_a;
    reg [1  : 0]    sdr_ba;
    reg [3  : 0]    cmd;
    reg             load_l, load_h;
    reg             sdr_cke;

    assign rd_bus = {sdr_cke, cmd, sdr_a, sdr_ba};

    always @(posedge clk)
    begin
        if (!read_en)
            count <= 8'b0;
        else if (count < 10)
            count <= count + 1'b1;
        else
            count <= count;
    end

    always @(posedge clk)
    begin : FSM_NODE
        if(!read_en) begin
            cmd <= `NOP;
            sdr_a <= 13'b0;
            sdr_ba <= 2'b0;
            sdr_cke <= 1'b1;
            read_done <= 1'b0;
            load_l <= 1'b0;
            load_h <= 1'b0;
        end
        else begin
            case (count)
                start : begin
                    cmd <= `ACT;
                    sdr_a <= int_addr[22 : 10];
                    sdr_ba <= int_addr[24 : 23];
                end
                read : begin
                    cmd <= `RD;
                    sdr_a[9 : 0] <= int_addr[9 : 0];
                    sdr_ba <= int_addr[24 : 23];
                    sdr_a[10] <= 1'b1;
                end
                loadl : begin
                    cmd <= `NOP;
                    load_l <= 1'b1;
                end
                loadh : begin
                    cmd <= `NOP;
                    load_h <= 1'b1;
                    load_l <= 1'b0;
                end
                finish : begin
                    load_h <= 1'b0;
                    read_done <= 1'b1;
                end
                default : cmd <= `NOP;
            endcase
        end
    end

    reg [15 : 0]    dq_cap;

    always @(posedge cap_clk)
    begin : CAP_REG_NODE
        if (!read_en)
            dq_cap <= 16'b0;
        else
            dq_cap <= sdr_dq;
    end

    reg [15 : 0]    dq_sys0, dq_sys;

    always @(posedge clk)
    begin : SYNC_REG_NODE
        if (!read_en) begin
            dq_sys0 <= 16'b0;
            dq_sys <= 16'b0;
        end
        else begin
            dq_sys0 <= dq_cap;
            dq_sys <= dq_sys0;
        end
    end

    always @(posedge clk)
    begin : FITTER_NODE
        if (!read_en)
            rdata <= 32'b0;
        else begin
            if (load_l) rdata[15 : 0] <= dq_sys;
            if (load_h) rdata[31 : 16] <= dq_sys;
        end
    end

endmodule 